﻿
#include "app.hpp"

#include <vector>

#include "controller/meet_controller.hpp"
#include "controller/device_controller.hpp"
#include "controller/sys_controller.hpp"
#include "controller/test_controller.hpp"
#include "db/sqlite_conn.hpp"
#include "service/ws_server.hpp"
#include "wlog.hpp"
#include "service/serv_manage.hpp"
#include "service/device_state.hpp"
#include "conf/conf.hpp"
#include "utils/write_log.hpp"
namespace bz
{


	

	app::app()
	{

	}

	

	void app::init(string home_path, string app_path, std::set<string> ip_set,std::function<void(int& port)> cb)
	{
		local_ip_set_ = ip_set;
		on_inited_ = cb;
		home_dir_ = home_path;
		app_dir_ = app_path;
		write_log::instance()->init(app_dir_);
		timer_ = make_shared<AsioTimer>();

		conf::instance()->init(app_dir_+"/conf/config.ini");
		string edition = conf::instance()->get_conf<string>("common/edition");
		//http_thread_ = make_shared<std::thread>(&app::http_run, this);
		//http_thread_->detach();

		auto res = sqlite_conn::instance()->init(app_dir_, edition);
		if (res)
		{
			device_state::instance();
			http_start();
		}
		
	}

	

	void allow_cross_domain(coro_http_response& res)
	{
		res.add_header("Access-Control-Allow-Origin", "*");
		res.add_header("Access-Control-Allow-Methods", "GET, POST, HEAD, PUT, DELETE, OPTIONS");
		res.add_header("Access-Control-Expose-Headers", "Server,range,Content-Length,Content-Range");
		res.add_header("Access-Control-Allow-Headers", "origin,range,accept-encoding,referer,Cache-Control,X-Proxy-Authorization,X-Requested-With,Content-Type");
	}

	struct check : public base_aspect {
		bool before(coro_http_request& req, coro_http_response& res) {
			allow_cross_domain(res);
			if (req.get_method() == "OPTIONS")
			{
				res.set_status_and_content(status_type::ok, "");
				return false;
			}
			res.add_header("Content-Type","application/json; charset=UTF-8");
			return true;
		}

		bool after(coro_http_request& req, coro_http_response& res) {
			return true;
		}
	};


	void app::http_start()
	{
		//serv_manage::instance()->init("");
		http_port_ = 17700;
		
		http_server_ = make_shared<coro_http_server>(1, http_port_);


		ws_server* ws_serv = new ws_server();
		device_controller* device_ctrl = new device_controller();

		meet_controller* meet_ctrl = new meet_controller();
		sys_controller* sys_ctrl = new sys_controller();
		test_controller* test_ctrl = new test_controller();
		std::vector<std::shared_ptr<base_aspect>> checkaspect = { std::make_shared<check>() };

		/*http_server_->set_http_handler<GET, POST, OPTIONS>("/", [](coro_http_request& req, coro_http_response& resp) {
			resp.set_status_and_content(status_type::ok, "hello world");
		}, std::vector{ std::make_shared<check>()});*/

		http_server_->set_http_handler<GET, POST, OPTIONS>(
			"/get", [](coro_http_request& req, coro_http_response& resp) {
				std::cout << "http thread id =" << std::this_thread::get_id()
					<< std::endl;
				resp.set_status_and_content(status_type::ok, "ggg");
			});


		http_server_->set_http_handler<GET, POST>("/test", [](coro_http_request& req, coro_http_response& res)->async_simple::coro::Lazy<void> {
			//co_await ws_manage::instance()->broadcast_room_msg("cccccccccccc");

			/*co_await coro_io::post([&]{
				fme_client* fme = new fme_client("192.168.0.50", "admin", "P@rad1se");
				async_simple::coro::syncAwait(fme->connect_ws());
				fme->add_ws_subscrible("c01c7efb-dd02-4e8f-a75f-4bee846fb6fd");
			});*/
			
			res.set_status_and_content(status_type::ok, "hello world");

			co_return;

			}, checkaspect);
		WLOG << "ws_serv point=" << ws_serv;
		http_server_->set_http_handler<cinatra::GET>("/ws", &ws_server::hand, ws_serv);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/device/all_list", &device_controller::all_list, device_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/device/add", &device_controller::add, device_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/device/remove", &device_controller::remove, device_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/device/batch_remove", &device_controller::batch_remove, device_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/device/update", &device_controller::update, device_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/device/type_list", &device_controller::type_list, device_ctrl, checkaspect);



	

		http_server_->set_http_handler<GET, POST, OPTIONS>("/meet/index", &meet_controller::index, meet_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/meet/add", &meet_controller::add, meet_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/meet/remove", &meet_controller::remove, meet_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/meet/edit_get", &meet_controller::edit_get, meet_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/meet/update", &meet_controller::update, meet_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/meet/get", &meet_controller::get, meet_ctrl, checkaspect);

		http_server_->set_http_handler<GET, POST, OPTIONS>("/meet/hand_terminal", &meet_controller::hand_terminal, meet_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/meet/muti_hand_terminal", &meet_controller::muti_hand_terminal, meet_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/meet/hand_all_sound", &meet_controller::hand_all_sound, meet_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/meet/hand_all_invite", &meet_controller::hand_all_invite, meet_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/meet/change_layout", &meet_controller::change_layout, meet_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/meet/get_poll_setting", &meet_controller::get_poll_setting, meet_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/meet/add_poll_plan", &meet_controller::add_poll_plan, meet_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/meet/update_poll_plan", &meet_controller::update_poll_plan, meet_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/meet/remove_poll_plan", &meet_controller::remove_poll_plan, meet_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/meet/set_meet_poll", &meet_controller::set_meet_poll, meet_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/meet/hand_ter_poll", &meet_controller::hand_ter_poll, meet_ctrl, checkaspect);

		http_server_->set_http_handler<GET, POST, OPTIONS>("/meet/start_meet", &meet_controller::start_meet, meet_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/meet/end_meet", &meet_controller::end_meet, meet_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/meet/hand_poll", &meet_controller::hand_poll, meet_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/meet/subscribe_terminal_detail", &meet_controller::subscribe_terminal_detail, meet_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/meet/unsubscribe_terminal_detail", &meet_controller::unsubscribe_terminal_detail, meet_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/meet/camera_control", &meet_controller::camera_control, meet_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/meet/get_terminal_detail", &meet_controller::get_terminal_detail, meet_ctrl, checkaspect);

		

		http_server_->set_http_handler<GET, POST, OPTIONS>("/meet/hand_link", &meet_controller::hand_link, meet_ctrl, checkaspect);
		
		http_server_->set_http_handler<GET, POST, OPTIONS>("/meet/change_main", &meet_controller::change_main, meet_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/meet/invite_terminal", &meet_controller::invite_terminal, meet_ctrl, checkaspect);




		http_server_->set_http_handler<GET, POST, OPTIONS>("/sys/get_current_mcu", &sys_controller::get_current_mcu, sys_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/sys/get_active_status", &sys_controller::get_active_status, sys_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/sys/active_license", &sys_controller::active_license, sys_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/sys/login", &sys_controller::login, sys_ctrl, checkaspect);








		http_server_->set_http_handler<GET, POST, OPTIONS>("/test/test_create_cospace", &test_controller::test_create_cospace, test_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/test/clear_all_calls", &test_controller::clear_all_calls, test_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/test/db_test1", &test_controller::db_test1, test_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/test/db_test2", &test_controller::db_test2, test_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/test/on_publish", &test_controller::on_publish, test_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/test/xd_test", &test_controller::xd_test, test_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/test/xd_create_temp", &test_controller::xd_create_temp, test_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/test/xd_device_list", &test_controller::xd_device_list, test_ctrl, checkaspect);
		http_server_->set_http_handler<GET, POST, OPTIONS>("/test/xd_clear_tmp", &test_controller::xd_clear_tmp, test_ctrl, checkaspect);



		std::errc ec;
		for (int i = 0; i < 20; ++i)
		{
			http_port_ += i;
			http_server_->set_http_port(http_port_);
			ec = http_server_->listen();
			if (ec == std::errc{}) {
				break;
			}
			
		}


		if (ec != std::errc{})
		{
			exit(1);
		}

		if (on_inited_) {
			on_inited_(http_port_);
		}

		http_server_->async_start();

		
		
	}
}
